// Environment Variable Management for Agent-MCP
// Handles reading, writing, and managing .env file through TUI

import { existsSync, readFileSync, writeFileSync, appendFileSync } from 'fs';
import { join } from 'path';
import { getProjectDir } from './config.js';

export interface EnvVariable {
  key: string;
  value: string | undefined;
  required: boolean;
  description: string;
  category: 'embedding' | 'cli' | 'system' | 'optional';
}

export const MANAGED_ENV_VARS: EnvVariable[] = [
  // Embedding Provider Keys
  {
    key: 'OPENAI_API_KEY',
    value: undefined,
    required: false,
    description: 'OpenAI API key for embeddings and chat completion',
    category: 'embedding'
  },
  {
    key: 'HUGGINGFACE_API_KEY',
    value: undefined,
    required: false,
    description: 'HuggingFace API key for embedding models',
    category: 'embedding'
  },
  {
    key: 'GEMINI_API_KEY',
    value: undefined,
    required: false,
    description: 'Google Gemini API key for embeddings',
    category: 'embedding'
  },
  {
    key: 'ANTHROPIC_API_KEY',
    value: undefined,
    required: false,
    description: 'Anthropic Claude API key for CLI agents',
    category: 'cli'
  },
  // System Configuration
  {
    key: 'EMBEDDING_PROVIDER',
    value: undefined,
    required: false,
    description: 'Default embedding provider (openai, ollama, huggingface, gemini)',
    category: 'system'
  },
  {
    key: 'MCP_DEBUG',
    value: undefined,
    required: false,
    description: 'Enable debug logging (true/false)',
    category: 'system'
  },
  // Optional Services
  {
    key: 'OLLAMA_HOST',
    value: undefined,
    required: false,
    description: 'Ollama service host URL (default: http://localhost:11434)',
    category: 'optional'
  },
  {
    key: 'LOCAL_SERVER_URL',
    value: undefined,
    required: false,
    description: 'Local embedding server URL',
    category: 'optional'
  }
];

function getEnvFilePath(): string {
  return join(getProjectDir(), '.env');
}

export function loadEnvFile(): Map<string, string> {
  const envPath = getEnvFilePath();
  const envVars = new Map<string, string>();
  
  if (!existsSync(envPath)) {
    return envVars;
  }
  
  try {
    const content = readFileSync(envPath, 'utf-8');
    const lines = content.split('\n');
    
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed && !trimmed.startsWith('#')) {
        const equalIndex = trimmed.indexOf('=');
        if (equalIndex > 0) {
          const key = trimmed.substring(0, equalIndex).trim();
          const value = trimmed.substring(equalIndex + 1).trim()
            .replace(/^["']/, '')  // Remove leading quote
            .replace(/["']$/, ''); // Remove trailing quote
          envVars.set(key, value);
        }
      }
    }
  } catch (error) {
    console.warn(`Warning: Could not read .env file: ${error}`);
  }
  
  return envVars;
}

export function saveEnvFile(envVars: Map<string, string>): void {
  const envPath = getEnvFilePath();
  const lines: string[] = [];
  
  // Add header comment
  lines.push('# Agent-MCP Environment Configuration');
  lines.push('# Generated by Agent-MCP TUI Configuration');
  lines.push('# ' + new Date().toISOString());
  lines.push('');
  
  // Group by category
  const categories = ['embedding', 'cli', 'system', 'optional'] as const;
  
  for (const category of categories) {
    const categoryVars = MANAGED_ENV_VARS.filter(v => v.category === category);
    if (categoryVars.length === 0) continue;
    
    // Category header
    const categoryName = category.charAt(0).toUpperCase() + category.slice(1);
    lines.push(`# ${categoryName} Configuration`);
    
    for (const envVar of categoryVars) {
      const value = envVars.get(envVar.key);
      if (value !== undefined && value !== '') {
        lines.push(`${envVar.key}="${value}"`);
      } else {
        lines.push(`# ${envVar.key}=  # ${envVar.description}`);
      }
    }
    lines.push('');
  }
  
  // Add any other existing vars that aren't managed
  const existingVars = loadEnvFile();
  const otherVars: string[] = [];
  
  for (const [key, value] of existingVars) {
    if (!MANAGED_ENV_VARS.find(v => v.key === key)) {
      otherVars.push(`${key}="${value}"`);
    }
  }
  
  if (otherVars.length > 0) {
    lines.push('# Other Configuration');
    lines.push(...otherVars);
    lines.push('');
  }
  
  try {
    writeFileSync(envPath, lines.join('\n'));
  } catch (error) {
    console.error(`Error writing .env file: ${error}`);
    throw error;
  }
}

export function getCurrentEnvValues(): Map<string, string> {
  const current = new Map<string, string>();
  const fileVars = loadEnvFile();
  
  for (const envVar of MANAGED_ENV_VARS) {
    // Priority: process.env > .env file
    const processValue = process.env[envVar.key];
    const fileValue = fileVars.get(envVar.key);
    
    if (processValue) {
      current.set(envVar.key, processValue);
    } else if (fileValue) {
      current.set(envVar.key, fileValue);
    }
  }
  
  return current;
}

export function setEnvVariable(key: string, value: string): void {
  const envVars = loadEnvFile();
  envVars.set(key, value);
  saveEnvFile(envVars);
  
  // Also update the current process environment
  process.env[key] = value;
}

export function removeEnvVariable(key: string): void {
  const envVars = loadEnvFile();
  envVars.delete(key);
  saveEnvFile(envVars);
  
  // Also remove from current process environment
  delete process.env[key];
}

export function validateApiKey(key: string, value: string): { valid: boolean; message?: string } {
  if (!value || value.trim() === '') {
    return { valid: false, message: 'API key cannot be empty' };
  }
  
  // Basic validation patterns for different services
  switch (key) {
    case 'OPENAI_API_KEY':
      if (!value.startsWith('sk-') || value.length < 20) {
        return { valid: false, message: 'OpenAI API key should start with "sk-" and be at least 20 characters' };
      }
      break;
    case 'ANTHROPIC_API_KEY':
      if (!value.startsWith('sk-ant-') || value.length < 20) {
        return { valid: false, message: 'Anthropic API key should start with "sk-ant-" and be at least 20 characters' };
      }
      break;
    case 'HUGGINGFACE_API_KEY':
      if (!value.startsWith('hf_') || value.length < 10) {
        return { valid: false, message: 'HuggingFace API key should start with "hf_" and be at least 10 characters' };
      }
      break;
    case 'GEMINI_API_KEY':
      if (value.length < 10) {
        return { valid: false, message: 'Gemini API key should be at least 10 characters' };
      }
      break;
  }
  
  return { valid: true };
}

export function maskApiKey(value: string): string {
  if (!value || value.length < 8) {
    return '***';
  }
  
  const start = value.substring(0, 4);
  const end = value.substring(value.length - 4);
  const middle = '*'.repeat(Math.max(4, value.length - 8));
  
  return `${start}${middle}${end}`;
}

export function getEnvVariablesByCategory(category: 'embedding' | 'cli' | 'system' | 'optional'): EnvVariable[] {
  return MANAGED_ENV_VARS.filter(v => v.category === category);
}

export function reloadEnvironmentVariables(): void {
  // Reload environment variables from .env file into process.env
  const envVars = loadEnvFile();
  for (const [key, value] of envVars) {
    process.env[key] = value;
  }
}

export function isEnvVariableRequired(key: string, embeddingProvider?: string): boolean {
  const envVar = MANAGED_ENV_VARS.find(v => v.key === key);
  if (!envVar) return false;
  
  // Dynamic requirements based on selected embedding provider
  if (embeddingProvider) {
    switch (key) {
      case 'OPENAI_API_KEY':
        return embeddingProvider === 'openai';
      case 'HUGGINGFACE_API_KEY':
        return embeddingProvider === 'huggingface';
      case 'GEMINI_API_KEY':
        return embeddingProvider === 'gemini';
    }
  }
  
  return envVar.required;
}